Flux の失敗は Store に Store という名前をつけたこと
強い言い方だけど、Flux Architecture の失敗として Store に Store という名前をつけたことがあると思っている。
あるいは、黎明期の Flux は Store という名前で良かったんだけど、 #Redux はその名前を引き継がないほうが良かったんじゃないかと思っている。 なぜかと言うと、Store という名前はストレージ抽象っぽい印象を与えるからだ。
「フロントエンドに DB っぽい概念が欲しいから Store というものを作るのね」という仕方で Redux を理解している人をたまに見るし、なんならそういう発想で作られたライブラリもあるが、あんまり良い発想ではないと思う( たとえば redux-orm のような「クライアントサイド ORM」について、中級者は単なる normalizer 用途として割り切ることもできるだろうが、初心者にこれらを与えるのはいらぬ誤解を生むと思う )。
たとえ広い意味で「DB っぽい」ということに同意したとしても、サーバーサイドの MySQL や PostgreSQL の使い方をアナロジーに使うのは問題が大きい(使うならせめて時系列データベースとか出して欲しい。私は時系列データベースに詳しくないのでそういう説明はできないが)。
Redux にリレーショナルなデータを置くこともあるとはいえ、基本的に最新状態のスナップショットしか置かないことが一般化した現代のアプリケーション開発者に RDB のメタファーを与えると「状態変化」という視点が抜け落ちてしまう。
じゃぁどう Store を理解するのが良いかというと、(上で時系列とか出したように)「時間の流れの抽象」として捉えるのが良いと思う。たとえば Rx は Stream という名前を使っている。Stream は Flux に限らず何にでも使える概念だが、Store も時系列を持ったデータの流れの一種で、どちらかというとそっちの仲間と理解するほうが良い。
突然 Rx が出てきた理由がわからない人はためしに RxJS の scan オペレータを使って Redux を自前再実装してみると良いと思う。私は Rx を直接使うのは複雑すぎて好きではないのだが、ここで言いたいのは、概念の命名は Redux より Rx の方が上手いのでそこから学べることはあるということだ。
#Reducer_はなぜ_reduce_なのか で触れたように、action は画面内で起こった出来事を表すオブジェクトで、dispatch は新しい action を時系列上に流す(つまり時間を +1 進める)操作にあたる。reducer はさっきの状態と今起こった出来事から次の状態を作る関数だ。 そして Store は dispatch(時間を進める関数)とたくさんの reducer(時間が進んだ時にどういう状態変化をするか)を内に抱えるオブジェクトだと考えると、これはもう「Store = 時系列そのものを表すオブジェクト」と考えるほうが自然ではないだろうか(ちなみに Rx で Redux を再現した場合、dispatch は RxJS の next() メソッドで実装される。dispatch よりも next の方がこの点でもニュアンスを正確に表現していて良いと思う)。もし Flux を図に描けと言われた場合、Store は三段の円柱で描くよりも年表や時計や矢印の絵で描いたほうが良いまでないだろうか。
確かに中に抱える「現在の状態」はリレーショナルな JSON オブジェクトかもしれないが、Store はあくまでそれらを包括する「時間の流れ」を表すものと説明した方が良い。EventStream というか ActionTimeline というか SnapshotSequence というか……何でも良いが、少なくとも Redux の Store は実態としてそういう概念になっている。